home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / byt86jan.arc / FRAMES.PRO < prev    next >
Encoding:
Text File  |  1985-12-27  |  6.1 KB  |  217 lines

  1.  
  2. /* get the Value of Slot in a given Frame */
  3. frame_get(Frame,Slot,Value) :-
  4.     ffget(Frame,Frame,Slot,Value).
  5.  
  6. ffget(Parameter_Frame,Frame,Slot,Value) :-  /* check for a value Facet */
  7.     fget(Frame,Slot,value,Value).
  8. ffget(Parameter_Frame,Frame,Slot,Value) :-  /* does it have a default? */
  9.     fget(Frame,Slot,default,Value).
  10. ffget(Parameter_Frame,Frame,Slot,Value) :-  /* how about a demon?      */
  11.     fget(Frame,Slot,if_needed,Rule),
  12.     F =.. [Rule,Parameter_Frame,Value],
  13.     F.
  14. ffget(Parameter_Frame,Frame,Slot,Value) :-  /* none of the above */
  15.     fget(Frame,ako,value,Parent),    /* so, move up the hierarchy */
  16.     ffget(Parameter_Frame,Parent,Slot,Value).
  17.  
  18. fget(Frame,Slot,Facet,Value) :-    /* just grab the given Facet or fail */
  19.     F =.. [Frame,Slot,Facet,Value],
  20.     F.
  21.  
  22.  
  23.  
  24. /* put Value in Slot of a given Frame.    If this Slot has an associated
  25.    if_added demon, then grab it and execute it    after  installing the
  26.    given Value.
  27. */
  28. frame_put(Frame,Slot,Value) :-
  29.     get_rule(Frame,Slot,if_added,Rule), /* must we do something extra */
  30.     fput(Frame,Slot,value,Value),
  31.     F =.. [Rule,Frame,Value],         
  32.     F.
  33. frame_put(Frame,Slot,Value) :-
  34.     fput(Frame,Slot,value,Value).        /* just a simple fput will do */
  35.  
  36. fput(Frame,Slot,Facet,Value) :-
  37.     F =.. [Frame,Slot,Facet,Value],
  38.     assertz(F).
  39.  
  40.  
  41.  
  42.  
  43. /* remove Slot from a given Frame.  If the Slot has an associated
  44.    if_removed demon, then grab the rule and execute it    before ,
  45.    removing the Slot.
  46. */
  47. frame_remove(Frame,Slot) :-
  48.     get_rule(Frame,Slot,if_removed,Rule),  /* something extra to do */
  49.     F =.. [Rule,Frame],
  50.     F,
  51.     fremove(Frame,Slot).
  52. frame_remove(Frame,Slot) :-
  53.     fremove(Frame,Slot).       /* just a simple fremove */
  54.  
  55. fremove(Frame,Slot) :-
  56.     F =.. [Frame,Slot,value,Value],
  57.     retract(F).
  58. fremove(_,_).        /* if Slot doesn't exist, then no harm done */
  59.  
  60.  
  61.  
  62.  
  63. /*  replace whatever is in Slot with Value.  If the Slot has an associated 
  64.     if_replaced rule, then grab it and execute it  after  doing the
  65.     replacement.
  66. */
  67. frame_replace(Frame,Slot,Value) :-
  68.     get_rule(Frame,Slot,if_replaced,Rule), /* something extra to do */
  69.     freplace(Frame,Slot,Value),
  70.     F =.. [Rule,Frame],
  71.     F.
  72. frame_replace(Frame,Slot,Value) :-
  73.     freplace(Frame,Slot,Value).           /* just a simple replace */
  74.  
  75. freplace(Frame,Slot,Value) :-
  76.     fremove(Frame,Slot),
  77.     frame_put(Frame,Slot,Value).
  78.  
  79.  
  80.  
  81.  
  82.  
  83. /* append Value to the list in Slot.  If Slot has an associated 
  84.    if_appended rule, then grab it and execute it  after  appending
  85.    the Value.
  86. */
  87. frame_append(Frame,Slot,Value) :-
  88.     get_rule(Frame,Slot,if_appended,Rule),
  89.     fappend(Frame,Slot,Value),
  90.     F =.. [Rule,Frame],
  91.     F.
  92. frame_append(Frame,Slot,Value) :-
  93.     fappend(Frame,Slot,Value).
  94.  
  95.  
  96. /* here we check to see if the slot already exists.  
  97.    If it does, then we just append the new Value to the old value list.  
  98.    If the Slot does not exist, then we create it and give it a value 
  99.    consisting of the list whose single element is Value.
  100. */
  101. fappend(Frame,Slot,Value) :-
  102.     fget(Frame,Slot,value,Old),
  103.     (member(Value,Old)
  104.     ;
  105.      fremove(Frame,Slot),
  106.      fput(Frame,Slot,value,[Value|Old])
  107.     ).
  108. fappend(Frame,Slot,Value) :-
  109.     fput(Frame,Slot,value,[Value]).
  110.  
  111.  
  112. /* this is a simple utility predicate used to travel up the frame
  113.    hierarchy looking for an appropriate rule to grab.
  114. */
  115. get_rule(Frame,Slot,Type,Rule) :-
  116.     fget(Frame,Slot,Type,Rule).
  117. get_rule(Frame,Slot,Type,Rule) :-
  118.     fget(Frame,ako,value,Parent),
  119.     get_rule(Parent,Slot,Type,Rule).
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126. /*  Example 
  127.  
  128. frame representation:
  129.  
  130.      cylinder
  131.       ako
  132.            value : thing
  133.       height
  134.            if_added : cylinder_height_add
  135.            if_removed : cylinder_height_remove
  136.       radius
  137.            if_added : cylinder_radius_add
  138.            If_removed : cylinder_radius_remove
  139.       cross_section
  140.            if_needed : cylinder_cross_section
  141.       volume
  142.            if_needed : cylinder_volume
  143.       
  144.      cylinder1
  145.       ako
  146.            value : cylinder
  147.  
  148.  
  149. comments:  cylinder1  above is an instance of cylinder.   When we 
  150. use frame_put(cylinder1,radius,2),  say,  the system will install 
  151. the  number  "2" as the value of cylinder1's radius and  it  will 
  152. further  compute cylinder1's cross sectional area and install  it 
  153. under the cross_section slot.  Similar actions take place when we 
  154. do a frame_put for cylinder1's height.   Below is the Prolog code 
  155. that implements all this.  NOTE: PDPROLOG only supports integer
  156. arithmetic.
  157. */
  158.  
  159.  
  160. cylinder(ako,value,geometric_object).
  161. cylinder(height,if_added,cylinder_height_add).
  162. cylinder(height,if_removed,cylinder_height_remove).
  163. cylinder(radius,if_added,cylinder_radius_add).
  164. cylinder(radius,if_removed,cylinder_radius_remove).
  165. cylinder(cross_section,if_needed,cylinder_cross_section).
  166. cylinder(volume,if_needed,cylinder_volume).
  167.  
  168. /* if we get the height, then we try to compute the cylinder's
  169.    volume.
  170. */
  171. cylinder_height_add(Cylinder,_) :-
  172.     cylinder_volume(Cylinder,_).
  173. cylinder_height_add(_,_).    /* if we can't do it, 
  174.                  e.g., the radius is unknown, 
  175.                  then no harm done */
  176.  
  177. /* if the height is removed, then the old volume is no 
  178.    longer valid 
  179. */
  180. cylinder_height_remove(Cylinder) :-
  181.     frame_remove(Cylinder,volume).
  182.  
  183. /* if we get the radius, then we can compute the cylinder's
  184.    cross sectional area
  185. */
  186. cylinder_radius_add(Cylinder,_) :-
  187.     cylinder_cross_section(Cylinder,_).
  188.  
  189. /* if the radius is removed, then the old cross sectional area
  190.    is no longer valid
  191. */
  192. cylinder_radius_remove(Cylinder) :-
  193.     frame_remove(Cylinder,cross_section),
  194.     frame_remove(Cylinder,volume).
  195.  
  196. /* PDPROLOG does not support floating-point arithmetic, so pi has been
  197.    approximated as 3.  If you are using a commercial prolog, change 3 to 3.1416
  198. */
  199. cylinder_cross_section(Cylinder,Cross_Section) :-
  200.     frame_get(Cylinder,radius,Radius),
  201.     Cross_Section is 3*Radius*Radius,
  202.     freplace(Cylinder,cross_section,Cross_Section).
  203.  
  204. cylinder_volume(Cylinder,Volume) :-
  205.     frame_get(Cylinder,cross_section,Cross_Section),
  206.     frame_get(Cylinder,height,Height),
  207.     Volume is Height*Cross_Section,
  208.     freplace(Cylinder,volume,Volume).
  209.  
  210. cylinder1(ako,value,cylinder).
  211.  
  212.  
  213. r,height,Height),
  214.     Volume is Height*Cross_Section,
  215.     freplace(Cylinder,volume,Volume).
  216.  
  217. cylinder1(ako,value,cylinde